---
title: DDD 最小闭环
sidebar_position: 0
---
使用一个贯穿始终的案例。我们会模仿真实的敏捷开发过程，把案例分成三个迭代，每个迭代的需求规模逐渐扩大，复杂性也逐渐增加。为了满足变化的需求，就会出现新的问题，为了解决这些问题，咱们就会引入新的 DDD 模式和实践，或者深化之前学过的知识。

通过迭代一，实现一个“麻雀虽小、五脏俱全”的项目。打通从需求分析，到领域建模，再到架构设计，最后到数据库和代码实现的完整闭环。


学完迭代一，你就可以理解 DDD 实践中那些最基本的套路了，甚至还可以在自己实际工作的项目里，选择一个小的“切片”，开始尝试落地 DDD。

<DocCardList/>

## 这次迭代的需求
很多中小企业，都有诸如考勤管理、工时管理、项目管理、请假管理等通用的需求。我们姑且把这些应用统称为“企业管理系统”。

领域指的是软件要解决的那些业务问题，所以也可以叫业务领域，英文叫 Business Domain。在这个例子里，**“企业管理”就是咱们要处理的领域**。


过去，这些企业只能自建或购买软件系统，安装到公司内部的服务器上，甚至还要有自己的机房，软硬件以及运维成本都比较高。如果咱们能够把这些应用放在云上，那么企业就只需要有选择地购买我们提供的服务，按需付费就好了，不再需要自建机房，也不需要自己运维，可以有效降低企业的成本。

这种系统，其实是基于 SaaS 的应用。所谓 SaaS，英文全称是 Software-as-a-Service，中文译作“软件即服务”。也就是说，软件不再像传统上那样交付并安装在客户本地，而是安装到云上，成为客户可以直接使用的服务。

SaaS 应用往往有个特点，用户五花八门，需求也是复杂多变。有些应用，如果只针对一个企业开发，本来挺简单，一旦放到云上，需求复杂性就会急剧上升。所以这次迭代，我们先做最简单的需求，后面两个迭代中我们再逐渐增加更多的灵活性。

由于不同行业的需求可能有较大差别，<RedSpan>我们决定先聚焦于一个细分市场，之后再扩大范围</RedSpan>。这个细分市场是我们比较熟悉的软件服务企业。这些企业会向自己的客户提供软件咨询、软件开发等等服务。

我们发现，这些企业的员工一般都工作在各个项目上。企业为了满足管理诉求，希望员工每周在系统中填报自己在哪些项目上花了多少时间，也就是所谓的报工时。所以我们第一步先来满足这个功能。但是，**为了完成报工时的功能，我们还要首先对组织、人员、项目等等进行管理**。


在领域驱动设计中有一个重要的角色叫做“领域专家”，叫业务专家也可以。领域专家需要对业务有总体性和本质性的把握，同时对业务发展也要有一定前瞻性，也就是说，心里要有一盘棋。

所以领域专家往往不是一线业务操作人员，在很多企业中，是那些干了很多年业务，逐渐成长起来的中级管理干部。还有一些企业，由产品经理担任领域专家。

那么，下面就由我暂时充当一下领域专家，详细说一下需求。


### 需求一：租户管理
这个系统可以给多家企业使用，每家企业的数据是隔离的。这些作为客户的企业，在云原生应用里，习惯上叫做“租户（tenant）”。<RedSpan>咱们的系统就是要对这些租户进行增删改查等管理</RedSpan>。这样的系统叫多租户系统。

假设我们做市场调研时，研究了一家叫“零零后科技有限公司”的企业，我们这个迭代，就先来满足这家企业的需求。

### 需求二：人员组织与管理


除了对租户进行增删改查等管理，我们还必须还有**人员和组织管理**。


零零后公司有多个开发中心，每个开发中心下有多个开发组。此外，还有公司直属的人事部、财务部等部门，系统要能够管理这些部门。


而且，我们对员工也要进行增删改查，并且把员工分配到部门。每个员工只能属于一个部门，比如王小牛属于开发一组。

下面这个图说明了需求中的人员和组织结构：

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202411241325696.png"/>

### 需求三：项目管理
接下来的需求是项目管理。

首先，租户要向它的客户提供服务，就要和客户签订合同，然后完成合同下的项目。比如说，租户零零后公司的客户可能包括 安安保险公司、开心电信等等。那么，租户零零后公司就得为安安保险公司，安排一堆程序员帮他们开发核心保险系统项目，也得为开心电信，安排几个咨询师帮他们得敏捷转型做咨询。
这里具体的需求是这样的：

* 一个租户企业可以有多个客户，可以在系统里对客户信息进行增删改查，每个客户都有一个客户经理来跟进；

* 租户可以和它的客户签订多份合同，在系统中对合同信息进行增删改查，每个合同都有一个销售人员负责，可以开始和结束合同；

* 一个合同下可以有多个项目，系统可以对项目进行增删改查，每个项目有一个项目经理；

* 可以在系统中开始和结束项目，需要记录开始和结束时间等信息。项目结束以后，很多事情就不能随便做了。

下图说明了客户、合同、项目等概念的关系：

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202411241537667.png"/>

### 需求四：人员分配
有了项目，我们就可以把员工分配到项目上，也可以让一个人退出项目。而且，一个项目可以有多个人参与，一个人又可以同时参与多个项目

除了这些，我们在把人分配到项目上的时候，还要记录每个人预计的投入百分比。比如说，王小牛在 A 项目上准备投入自己 30% 的时间，同时在 B 项目准备投入 40% 的时间等等。

之所以要记录预计的投入时间，是为了让企业能够在总体上调配人力资源。比如说管理人员看到王小牛还有 30% 的空余时间，就可以把它同时再安排到另一个项目上，以便实现“内卷最大化”。

下图说明了人员和项目投入的关系：

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202411241539005.png"/>

### 需求五：工时登记
把人员分配到项目上以后，我们就可以登记工时了。

我们这里规定只有当一个员工分配到一个项目上以后，才能通过这个项目报工时。这样的规定，一来是为了符合公司的管理要求，一个员工不能随意参加一个项目；二来也可以防止员工不小心把工时填到错误的项目上。

而且每个员工每周都需要在系统中填报工时，登记自己哪一天在哪个项目上投入了多少时间。当然，员工可对工时进行查询和修改，还可以为每天的投入的时间填写备注。你可以看一看工时登记的界面原型，进一步理解需求。

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202411241541328.png"/>

另外，尽管咱们尽量采用接近真实的案例，但也无法面面俱到。为了突出重点，我们这个课程还是省略了一些需求，比如说人员登录和权限控制等等。

现在，第一个迭代的需求基本上就说完了。这些需求看起来简单，其实关键点还是挺多的。而且更重要的是，在实际项目里，这些需求未必会这么清清楚楚、白纸黑字地列出来给你，更多是隐藏在领域专家的脑子里，需要我们去挖掘。

还有一些需求，我故意没有说得很详细，而是要在后续的开发过程中逐步揭示。这也是为了模拟实际项目的场景。

## DDD 的基本开发过程

下图表示了领域驱动设计中的主要流程。


<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202411241545356.png"/>


在整个开发流程中，首先是要捕获行为需求，也就是传统软件工程里的“**需求获取**”。这一步，我们要识别需求里有哪些流程、哪些功能，每个功能由什么人操作，会产生什么结果。

在传统软件工程中，这一步常用的方式是用例建模，也就是用 Use Case 来建模。在这套课程里面，我们会用 DDD 中比较流行的一种方法，叫做“事件风暴”。

接下来，我们就可以进行**领域建模**了，也就是通过建立领域模型，把需求里的主要业务知识描述清楚。DDD 的领域模型，大体上相当于传统软件工程中的分析模型。

基于领域模型，我们就可以做**架构设计**，包括进程间和进程内的架构。比如说微服务设计、中台设计都属于进程间架构。而 DDD 分层架构，通常说的是进程内架构。

然后就可以**根据领域模型进行数据库设计，最后是代码实现**。

这样，就形成了一个基于 DDD 的开发闭环。其实，在实践中，尤其是对敏捷软件开发来说，这些步骤不是线性的，而是反复迭代、互相穿插的。


DDD 是以领域模型为核心的。所以，我们可以把上面说的步骤分成模型的建立和模型的实现两部分。

模型的建立阶段，使用的都是业务术语，归根结底来自业务人员，业务人员不仅能听懂，而且负责评价建模的正确性。而模型的实现，则是业务人员不需要理解也不关注的，会包含技术实现方面的内容。这两者的边界很重要，我们在后面还会反复提到。

## 总结
领域就是软件要解决的业务问题。领域专家则是十分了解业务知识本质的人。

DDD 开发的基本流程是以领域模型为核心的。整个流程可以分为模型的建立和模型的实现两部分。其中模型的建立一定要使用业务语言，而模型的实现则增加了技术语言。模型的建立，是通过领域专家和开发人员的协作共同完成的。

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202411241558315.png"/>



